XfMissionChapterExecute={
	private ["_chapter_succeeded","_town_Elektrozavodsk","_town_Elektrozavodsk_pos","_town_Elektrozavodsk_size","_radio_task_updated","_train_task_updated","_tower_destroyed","_train_destroyed","_wagon_destroyed","_enemy_counts","_total_enemies","_last_reinforcement","_enemy_diff"];
	diag_log "";
	diag_log "=========================================================================";
	diag_log "                             CHAPTER 3                                   ";
	diag_log "=========================================================================";
	diag_log "";
	diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter3.sqf","XfMissionChapterExecute","Starting Chapter"];
	DM_Chapter_Enemies_Count = [0,[0,0,0,0]];
	DM_Mission_Chapter_CanRun = True;
	DM_Mission_Chapter_Runs = True;
	DM_Mission_Chapter_Success = 0;
	call XfMissionChapterSetup;
	_chapter_succeeded = false;
	if (!DM_Mission_Mission_CanRun) exitWith {diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter3.sqf","XfMissionChapterSetup","Mission canceled!"];};

	_town_Elektrozavodsk = d_town_markers select 2;
	_town_Elektrozavodsk_pos = _town_Elektrozavodsk select 0;
	_town_Elektrozavodsk_size = _town_Elektrozavodsk select 2;
	_radio_task_updated = false;
	_train_task_updated = false;
	// We record the initial amount of enemies, this allows for calling reinforcements only when it drops too low or too fast.
	// In the returned array, the first sub array is west count, the second is east count and the third is guerilla. Knowing our side, we know which one to take.
	_start_enemy_counts = ([DM_Chapter_Position,500,d_enemy_side] call XfMissionGetZoneSideCount) select 0;
	// This will accelerate a little the reinforcement rate.
	_enemy_diff = 5 + DM_Mission_RandomReinforcement;
	while {DM_Mission_Chapter_CanRun AND DM_Mission_Mission_CanRun} do {
		sleep 30;
		_enemy_counts = ([DM_Chapter_Position,500,d_enemy_side] call XfMissionGetZoneSideCount) select 0;
		_tower_destroyed = ["jip_tower_is_destroyed",False] call XNetGetJIP;
		_train_destroyed = ["jip_loco_is_destroyed",False] call XNetGetJIP;
		_wagon_destroyed = ["jip_wagon_is_destroyed",False] call XNetGetJIP;
		
		If (_tower_destroyed And (!_radio_task_updated)) then {
			["DestroyTheTower","", "","",[],"Succeeded"] call XfMissionTask;
			_radio_task_updated = True;
		};
		If (_train_destroyed And _wagon_destroyed And (!_train_task_updated)) then {
			["DestroyTheTrain","", "","",[],"Succeeded"] call XfMissionTask;
			"Congratulations, you destroyed the train!" call XfMissionMessageToAll;
			_train_task_updated = True;
			_chapter_succeeded = true;
			DM_Mission_Chapter_CanRun = false;
		};
		If (DM_Mission_Chapter_CanRun) then {
			// Send reinforcement if needed.
			If (((_start_enemy_counts - _enemy_counts) > _enemy_diff) && !_tower_destroyed) then {
				// If we get a value back from the function, it means a reinforcement was sent
				if (([d_enemy_side,[DM_Chapter_Position,200],DM_Mission_RandomReinforcement] call XfMissionRandomReinforcement) > 0) then {
					diag_log Format["(%1)[%2]: %3; %4 (%5 > %6)",diag_tickTime,"chapter1.sqf","XfMissionChapterExecute","Random reinforcement sent!",(_start_enemy_counts - _enemy_counts),_enemy_diff];
					hint "Reinforcement";
					// We raise the number of enemies which need to be killed to slow down reinforcement over time and eventually stop it.
					_enemy_diff = _enemy_diff + 2;
				};
			};
		};
	};
	sleep 30;
	if (DM_Mission_Mission_CanRun) then {
		if (_chapter_succeeded) then {
			call XfMissionChapterSuccess;
			// Waits until there are no more than 3 enemies left or the mission is replaced with a new one
			while{ (([DM_Chapter_Position,300,d_enemy_side] call XfMissionGetZoneSideCount) select 0) > 3 && DM_Mission_Mission_CanRun} do {
				sleep 10;
			};
			sleep 30;
		} else {
			call XfMissionChapterFailure;
		};
	} else {
		diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter3.sqf","XfMissionChapterSetup","Mission canceled!"];
	};
	call XfMissionChapterCleanUp;
	DM_Mission_Chapter_Runs = False;
};

XfMissionChapterSetup={
	private ["_town_Elektrozavodsk","_town_Elektrozavodsk_pos","_town_Elektrozavodsk_size","_mission_starter","_enemy_unit_groups","_unitgroup","_grpSpecOps1","_grpSpecOps2"];
	diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter3.sqf","XfMissionChapterSetup","Starting Initialization"];
	_town_Elektrozavodsk = d_town_markers select 2;
	_town_Elektrozavodsk_pos = _town_Elektrozavodsk select 0;
	_town_Elektrozavodsk_size = _town_Elektrozavodsk select 2;
	DM_Chapter_Position = _town_Elektrozavodsk_pos;
	// This indicates where the mission takes place
	[_town_Elektrozavodsk_pos,_town_Elektrozavodsk_size,_town_Elektrozavodsk select 1] call XfMissionCurrentPosition;
	// Position somewhat to the east of Elektrozavodsk, on the shore road
	[[11383.6,3335.77,0],250] call XfMissionPlaceStartTeleporter;
	// We set the shared variables
	["jip_loco_is_destroyed",False] call XNetSetIP;
	["jip_wagon_is_destroyed",False] call XNetSetIP;
	// We create the loco and wagon to destroy
	["Land_loco_742_blue",[[10178.1,2061.83,-0.013],255],"DESTROY",["","jip_loco_is_destroyed",True,1,["PipeBomb"]]] call XfMissionCreateMissionObject;
	["Land_wagon_tanker",[[10189.9,2064.96,-0.013],255],"DESTROY",["","jip_wagon_is_destroyed",True,1,["PipeBomb"]]] call XfMissionCreateMissionObject;
	// We set the shared variable
	["jip_tower_is_destroyed",False] call XNetSetIP;
	// We create the tower to destroy
	_tower_position = [_town_Elektrozavodsk_pos,_town_Elektrozavodsk_size,"Land_telek1",[10335.3,2183.64,0.00361156]] call  XfMissionRanObjectivePos;
	["Land_telek1",[_tower_position,random(360)],"DESTROY",["Congratulations, you destroyed the tower! The enemy cannot call reinforcement anymore!","jip_tower_is_destroyed",True,1,["PipeBomb"]]] call XfMissionCreateMissionObject;
	// We create the tasks
	["DestroyTheTower","Destoy the Radio Tower", "Destroying the radio tower will prevent the enemy from calling reinforcement!","",[],"Created"] call XfMissionTask;
	["DestroyTheTrain","Destroy the Chemicals Train", "The threat posed by the Chemicals contained in the train is huge! You need to destroy the train entirely, this will put the plans of the enemy to a stop!","",[],"Created"] call XfMissionTask;
	// We create the Mission markers on the map.
	[false,["chapter3_start_misson", [11383.6,3335.77,0], "ICON", "ColorBlue", [1,1],"Start",250,"hd_start","",1]] call XfMissionMarker;
	[false,["chapter3_tower_position", [10335.3,2183.64,0.00361156], "ICON", "ColorRed", [1,1],"Radio Tower",0,"hd_objective","",1]] call XfMissionMarker;
	[false,["chapter3_train_position", [10178.1,2061.83,-0.0140829], "ICON", "ColorRed", [1,1],"Train",0,"hd_objective","",1]] call XfMissionMarker;

	// We use the TaskDefend here to defend the area around the radio tower.
	// The floor(random(5)) will give a value between 0 and 4 included. 0,3,4 will give regular soldiers. 1 spetznatz and 2 snipers.
	_grpSoldiers1 = [d_enemy_side,[_tower_position,40],[],floor(random(5)),false] call XfMissionCreateFootmenGroup;
	// We use the TaskPatrol here to defend the area around the train.
	_grpSoldiers1 = [d_enemy_side,[[10178.1,2061.83,0],80],[],floor(random(5))] call XfMissionCreateFootmenGroup;
	// We spice up the location because it's a big town. No need to go overboard, since there are 2 more groups and snipers.
	// PowerOverride = 0, CoeffOverride = 0, PowerIncrement = 1, CoeffIncrement = 0
	[d_enemy_side,[_town_Elektrozavodsk_pos,_town_Elektrozavodsk_size],true,0,0,1,0] call XfMissionPopulateLocation;
	
	// We add at least 2 snipers to the whole town.
	if ((DM_Mission_Snipers select 0) <= 1) then {DM_Mission_Snipers = [2,2];};
	// This will create snipers automatically if selected in the mission setup
	[d_enemy_side,[_town_Elektrozavodsk_pos,_town_Elektrozavodsk_size],DM_Mission_Snipers] call XfMissionCreateSnipersArea;
	// This will create air support automatically if selected in the mission setup
	[d_enemy_side,[_town_Elektrozavodsk_pos,_town_Elektrozavodsk_size],DM_Mission_AirSupport] call XfMissionCallAirSupport;
};

XfMissionChapterSuccess={
	diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter3.sqf","XfMissionChapterSuccess","Starting"];
	DM_Mission_Chapter_Success = 1;
};

XfMissionChapterFailure={
	diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter3.sqf","XfMissionChapterFailure","Starting"];
	DM_Mission_Chapter_Success = -1;
};

// Self-explanatory
XfMissionChapterCleanUp={
	diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter3.sqf","XfMissionChapterCleanUp","Starting"];
	// Giving an empty position places the teleporter back to the hangar, closing the hangar.
	[[],0] call XfMissionPlaceStartTeleporter;
	// Giving only the marker name will trigger the deletion of the marker.
	[false,["chapter3_start_misson"]] call XfMissionMarker;
	[false,["chapter3_tower_position"]] call XfMissionMarker;
	[false,["chapter3_train_position"]] call XfMissionMarker;
	[] call XfMissionCleanObjects;
	[] call XfMissionCleanTriggers;
	[] call XfMissionCleanTasks;
};

DM_Mission_Chapter_Compiled = true;